home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / amiga / asrc29k.lha / tcpcmd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-08  |  7.1 KB  |  340 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "timer.h"
  4. #include "mbuf.h"
  5. #include "netuser.h"
  6. #include "internet.h"
  7. #include "tcp.h"
  8. #include "cmdparse.h"
  9. #include "commands.h"
  10.  
  11. static int doirtt __ARGS((int argc,char *argv[],void *p));
  12. static int domss __ARGS((int argc,char *argv[],void *p));
  13. static int dortt __ARGS((int argc,char *argv[],void *p));
  14. static int dotcpkick __ARGS((int argc,char *argv[],void *p));
  15. static int dotcpreset __ARGS((int argc,char *argv[],void *p));
  16. static int dotcpstat __ARGS((int argc,char *argv[],void *p));
  17. static int dotcptimer __ARGS((int argc,char *argv[],void *p));
  18. static int dotcptr __ARGS((int argc,char *argv[],void *p));
  19. static int dowindow __ARGS((int argc,char *argv[],void *p));
  20. static int tstat __ARGS((void));
  21.  
  22. /* TCP subcommand table */
  23. static struct cmds Tcpcmds[] = {
  24.     "irtt",        doirtt,        0, 0,    NULLCHAR,
  25.     "kick",        dotcpkick,    0, 2,    "tcp kick <tcb>",
  26.     "mss",        domss,        0, 0,    NULLCHAR,
  27.     "reset",    dotcpreset,    0, 2,    "tcp reset <tcb>",
  28.     "rtt",        dortt,        0, 3,    "tcp rtt <tcb> <val>",
  29.     "status",    dotcpstat,    0, 0,    NULLCHAR,
  30.     "timertype",    dotcptimer,    0, 0,    NULLCHAR,
  31.     "trace",    dotcptr,    0, 0,    NULLCHAR,
  32.     "window",    dowindow,    0, 0,    NULLCHAR,
  33.     NULLCHAR,
  34. };
  35. int
  36. dotcp(argc,argv,p)
  37. int argc;
  38. char *argv[];
  39. void *p;
  40. {
  41.     if(argc == 1)
  42.         return dotcpstat(argc,argv,p);
  43.     return subcmd(Tcpcmds,argc,argv,p);
  44. }
  45.  
  46. static int
  47. dotcptr(argc,argv,p)
  48. int argc;
  49. char *argv[];
  50. void *p;
  51. {
  52.     return setbool(&Tcp_trace,"TCP state tracing",argc,argv);
  53. }
  54.  
  55. /* Eliminate a TCP connection */
  56. static int
  57. dotcpreset(argc,argv,p)
  58. int argc;
  59. char *argv[];
  60. void *p;
  61. {
  62.     register struct tcb *tcb;
  63.  
  64.     tcb = (struct tcb *)ltop(htol(argv[1]));
  65.     if(!tcpval(tcb)){
  66.         tprintf(Notval);
  67.         return 1;
  68.     }
  69.     close_self(tcb,RESET);
  70.     return 0;
  71. }
  72.  
  73. /* Set initial round trip time for new connections */
  74. static int
  75. doirtt(argc,argv,p)
  76. int argc;
  77. char *argv[];
  78. void *p;
  79. {
  80.     struct tcp_rtt *tp;
  81.  
  82.     setlong(&Tcp_irtt,"TCP default irtt",argc,argv);
  83.     if(argc < 2){
  84.         for(tp = &Tcp_rtt[0];tp < &Tcp_rtt[RTTCACHE];tp++){
  85.             if(tp->addr != 0){
  86.                 if(tprintf("%s: srtt %lu mdev %lu\n",
  87.                  inet_ntoa(tp->addr),
  88.                  tp->srtt,tp->mdev) == EOF)
  89.                     break;
  90.             }
  91.         }
  92.     }
  93.     return 0;
  94. }
  95.  
  96. /* Set smoothed round trip time for specified TCB */
  97. static int
  98. dortt(argc,argv,p)
  99. int argc;
  100. char *argv[];
  101. void *p;
  102. {
  103.     register struct tcb *tcb;
  104.  
  105.     tcb = (struct tcb *)ltop(htol(argv[1]));
  106.     if(!tcpval(tcb)){
  107.         tprintf(Notval);
  108.         return 1;
  109.     }
  110.     tcb->srtt = atol(argv[2]);
  111.     return 0;
  112. }
  113.  
  114. /* Force a retransmission */
  115. static int
  116. dotcpkick(argc,argv,p)
  117. int argc;
  118. char *argv[];
  119. void *p;
  120. {
  121.     register struct tcb *tcb;
  122.  
  123.     tcb = (struct tcb *)ltop(htol(argv[1]));
  124.     if(kick_tcp(tcb) == -1){
  125.         tprintf(Notval);
  126.         return 1;
  127.     }
  128.     return 0;
  129. }
  130.  
  131. /* Set default maximum segment size */
  132. static int
  133. domss(argc,argv,p)
  134. int argc;
  135. char *argv[];
  136. void *p;
  137. {
  138.     return setshort(&Tcp_mss,"TCP MSS",argc,argv);
  139. }
  140.  
  141. /* Set default window size */
  142. static int
  143. dowindow(argc,argv,p)
  144. int argc;
  145. char *argv[];
  146. void *p;
  147. {
  148.     return setshort(&Tcp_window,"TCP window",argc,argv);    
  149. }
  150.  
  151. /* Display status of TCBs */
  152. static int
  153. dotcpstat(argc,argv,p)
  154. int argc;
  155. char *argv[];
  156. void *p;
  157. {
  158.     register struct tcb *tcb;
  159.  
  160.     if(argc < 2){
  161.         tstat();
  162.     } else {
  163.         tcb = (struct tcb *)ltop(htol(argv[1]));
  164.         if(tcpval(tcb))
  165.             st_tcp(tcb);
  166.         else
  167.             tprintf(Notval);
  168.     }
  169.     return 0;
  170. }
  171.  
  172. /* Dump TCP stats and summary of all TCBs
  173. /*     &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State
  174.  *     1234     0     0  xxx.xxx.xxx.xxx:xxxxx  xxx.xxx.xxx.xxx:xxxxx  Established
  175.  */
  176. static int
  177. tstat()
  178. {
  179.     register int i;
  180.     register struct tcb *tcb;
  181.     int j;
  182.  
  183.     for(j=i=1;i<=NUMTCPMIB;i++){
  184.         if(Tcp_mib[i].name == NULLCHAR)
  185.             continue;
  186.         tprintf("(%2u)%-20s%10lu",i,Tcp_mib[i].name,
  187.          Tcp_mib[i].value.integer);
  188.         if(j++ % 2)
  189.             tprintf("     ");
  190.         else
  191.             tprintf("\n");
  192.     }
  193.     if((j % 2) == 0)
  194.         tprintf("\n");
  195.  
  196.     tprintf("    &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State\n");
  197.     for(i=0;i<NTCB;i++){
  198.         for(tcb=Tcbs[i];tcb != NULLTCB;tcb = tcb->next){
  199.             tprintf("%8lx%6u%6u  ",ptol(tcb),tcb->rcvcnt,tcb->sndcnt);
  200.             tprintf("%-23s",pinet(&tcb->conn.local));
  201.             tprintf("%-23s",pinet(&tcb->conn.remote));
  202.             tprintf("%-s",Tcpstates[tcb->state]);
  203.             if(tcb->state == TCP_LISTEN && tcb->flags.clone)
  204.                 tprintf(" (S)");
  205.             if(tprintf("\n") == EOF)
  206.                 return 0;
  207.         }
  208.     }
  209.     return 0;
  210. }
  211. /* Dump a TCP control block in detail */
  212. void
  213. st_tcp(tcb)
  214. struct tcb *tcb;
  215. {
  216.     int32 sent,recvd;
  217.  
  218.     if(tcb == NULLTCB)
  219.         return;
  220.     /* Compute total data sent and received; take out SYN and FIN */
  221.     sent = tcb->snd.una - tcb->iss;    /* Acknowledged data only */
  222.     recvd = tcb->rcv.nxt - tcb->irs;
  223.     switch(tcb->state){
  224.     case TCP_LISTEN:
  225.     case TCP_SYN_SENT:    /* Nothing received or acked yet */
  226.         sent = recvd = 0;    
  227.         break;
  228.     case TCP_SYN_RECEIVED:
  229.         recvd--;    /* Got SYN, no data acked yet */
  230.         sent = 0;
  231.         break;
  232.     case TCP_ESTABLISHED:    /* Got and sent SYN */
  233.     case TCP_FINWAIT1:    /* FIN not acked yet */
  234.         sent--;
  235.         recvd--;
  236.         break;
  237.     case TCP_FINWAIT2:    /* Our SYN and FIN both acked */
  238.         sent -= 2;
  239.         recvd--;
  240.         break;
  241.     case TCP_CLOSE_WAIT:    /* Got SYN and FIN, our FIN not yet acked */
  242.     case TCP_CLOSING:
  243.     case TCP_LAST_ACK:
  244.         sent--;
  245.         recvd -= 2;
  246.         break;
  247.     case TCP_TIME_WAIT:    /* Sent and received SYN/FIN, all acked */
  248.         sent -= 2;
  249.         recvd -= 2;
  250.         break;
  251.     }
  252.     tprintf("Local: %s",pinet(&tcb->conn.local));
  253.     tprintf(" Remote: %s",pinet(&tcb->conn.remote));
  254.     tprintf(" State: %s\n",Tcpstates[tcb->state]);
  255.     tprintf("      Init seq    Unack     Next Resent CWind Thrsh  Wind  MSS Queue      Total\n");
  256.     tprintf("Send:");
  257.     tprintf("%9lx",tcb->iss);
  258.     tprintf("%9lx",tcb->snd.una);
  259.     tprintf("%9lx",tcb->snd.nxt);
  260.     tprintf("%7lu",tcb->resent);
  261.     tprintf("%6u",tcb->cwind);
  262.     tprintf("%6u",tcb->ssthresh);
  263.     tprintf("%6u",tcb->snd.wnd);
  264.     tprintf("%5u",tcb->mss);
  265.     tprintf("%6u",tcb->sndcnt);
  266.     tprintf("%11lu\n",sent);
  267.  
  268.     tprintf("Recv:");
  269.     tprintf("%9lx",tcb->irs);
  270.     tprintf("         ");
  271.     tprintf("%9lx",tcb->rcv.nxt);
  272.     tprintf("%7lu",tcb->rerecv);
  273.     tprintf("      ");
  274.     tprintf("      ");
  275.     tprintf("%6u",tcb->rcv.wnd);
  276.     tprintf("     ");
  277.     tprintf("%6u",tcb->rcvcnt);
  278.     tprintf("%11lu\n",recvd);
  279.  
  280.     if(tcb->reseq != (struct reseq *)NULL){
  281.         register struct reseq *rp;
  282.  
  283.         tprintf("Reassembly queue:\n");
  284.         for(rp = tcb->reseq;rp != (struct reseq *)NULL; rp = rp->next){
  285.             if(tprintf("  seq x%lx %u bytes\n",
  286.              rp->seg.seq,rp->length) == EOF)
  287.                 return;
  288.         }
  289.     }
  290.     if(tcb->backoff > 0)
  291.         tprintf("Backoff %u ",tcb->backoff);
  292.     if(tcb->flags.retran)
  293.         tprintf("Retrying ");
  294.     switch(tcb->timer.state){
  295.     case TIMER_STOP:
  296.         tprintf("Timer stopped ");
  297.         break;
  298.     case TIMER_RUN:
  299.         tprintf("Timer running (%ld/%ld ms) ",
  300.          (long)MSPTICK * read_timer(&tcb->timer),
  301.          (long)MSPTICK * dur_timer(&tcb->timer));
  302.         break;
  303.     case TIMER_EXPIRE:
  304.         tprintf("Timer expired ");
  305.     }
  306.     tprintf("SRTT %ld ms Mean dev %ld ms\n",tcb->srtt,tcb->mdev);
  307. }
  308.  
  309. /* tcp timers type - linear v exponential */
  310. static
  311. dotcptimer(argc,argv,p)
  312. int argc ;
  313. char *argv[] ;
  314. void *p ;
  315. {
  316.     extern int tcptimertype;
  317.  
  318.     if (argc < 2) {
  319.         tprintf("Tcp timer type is %s\n", tcptimertype ? "linear" : "exponential" ) ;
  320.         return 0 ;
  321.     }
  322.     
  323.     switch (argv[1][0]) {
  324.         case 'l':
  325.         case 'L':
  326.             tcptimertype = 1 ;
  327.             break ;
  328.         case 'e':
  329.         case 'E':
  330.             tcptimertype = 0 ;
  331.             break ;
  332.         default:
  333.             tprintf("use: tcp timertype [linear|exponential]\n") ;
  334.             return -1 ;
  335.     }
  336.  
  337.     return 0 ;
  338. }
  339.  
  340.